#ifndef MLIR_TOY_VISITOR_H
#define MLIR_TOY_VISITOR_H

#include <map>

#include "toyBaseVisitor.h"
#include "toyLexer.h"
#include "toyParser.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Verifier.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopedHashTable.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
#include "myDialect/toyDialect.h"
#include "myDialect/toyOps.h"
#include "myDialect/toyTypes.h"

class MLIRToyVisitor : public toyBaseVisitor {
public:
    MLIRToyVisitor(std::string filename, mlir::MLIRContext& context);

    mlir::ModuleOp getModule();

private:
    // symbol table
    std::map<std::string, mlir::Value> symbolTable;
    // top level module
    mlir::ModuleOp theModule;
    // mlir op builder
    mlir::OpBuilder builder;

    // file name
    std::string filename;
    
    // add symbol
    void addSymbol(llvm::StringRef name, mlir::Value theVal);

    // print symbols
    void printSymbol();

    // locate object
    mlir::Location loc(int line, int row);    

    std::any visitModule(toyParser::ModuleContext *ctx) override;

    std::any visitStmt(toyParser::StmtContext *ctx) override;
    
    std::any visitVar_assign(toyParser::Var_assignContext *ctx) override;

    std::any visitExpression(toyParser::ExpressionContext *ctx) override;

    std::any visitPrint_op(toyParser::Print_opContext *ctx) override;

    std::any visitPrim_expr(toyParser::Prim_exprContext *ctx) override;

};


#endif